package com.example.demo.controller;

import cn.hutool.core.io.file.FileNameUtil;
import com.example.demo.Interceptor.BzException;
import com.example.demo.Interceptor.ResponseEntity;
import com.example.demo.rpc.ApiUtils;
import com.example.demo.rpc.Wav;
import com.example.demo.utils.PcmCovWavUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 文件服务
 *
 * @author YZD
 */
@Api(tags = "语音转文本服务")
@RestController
@Valid
public class ServerController {

    private static final Logger LOGGER = LoggerFactory.getLogger(ServerController.class);

    @ApiOperation(value = "上传wav或pcm文件并转写")
    @PostMapping("/fileConvert")
    @ResponseBody
    public ResponseEntity<String> fileConvert(@NotNull(message = "文件不能为空") @RequestParam("file") MultipartFile file) {

        String suffix = FileNameUtil.getSuffix(file.getOriginalFilename());
        boolean beanAudio = "wav".equalsIgnoreCase(suffix) || "pcm".equalsIgnoreCase(suffix);
        if (file.isEmpty()) {
            throw new BzException("上传文件失败!");
        }
        if (!beanAudio) {
            throw new BzException("上传文件类型仅支持pcm和wav!");
        }

        String fileName = file.getOriginalFilename();
        try {

            Wav waveFile = new Wav();

            if ("pcm".equalsIgnoreCase(suffix)) {
                // 临时 存储
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                byte[] bytes = file.getBytes();
                try {
                    byteArrayOutputStream.write(bytes);
                } catch (IOException e) {
                    try {
                        byteArrayOutputStream.close();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                    e.printStackTrace();
                    throw new BzException("获取文件内容失败!");
                }

                // 内存处理 pcm转wav
                ByteArrayOutputStream pcmStream = new ByteArrayOutputStream();
                PcmCovWavUtil.convertWaveFile(byteArrayOutputStream, pcmStream);

                waveFile.GetFromBytes(pcmStream.toByteArray());
            } else {
                waveFile.GetFromBytes(file.getBytes());
            }

            String result = ApiUtils.sendToServer("qwertasd", waveFile.fs, waveFile.samples);
            LOGGER.info("fileName:[{}],result:[{}]", fileName, result);

            return ResponseEntity.success(result);
        } catch (IOException e) {
            LOGGER.error(e.toString(), e);
        }

        throw new BzException("转文字失败!");
    }


    @Deprecated
    @ApiOperation(value = "上传wav文件并转写")
    @PostMapping("/wavConvert")
    @ResponseBody
    public ResponseEntity<String> wavConvert(@RequestParam("file") MultipartFile file) {

        if (file.isEmpty() || !"wav".equalsIgnoreCase(FileNameUtil.getSuffix(file.getOriginalFilename()))) {
            throw new BzException("上传wav文件失败!");
        }

        String fileName = file.getOriginalFilename();
        try {

            Wav waveFile = new Wav();
            waveFile.GetFromBytes(file.getBytes());

            String result = ApiUtils.sendToServer("qwertasd", waveFile.fs, waveFile.samples);
            LOGGER.info("fileName:[{}],result:[{}]", fileName, result);

            return ResponseEntity.success(result);
        } catch (IOException e) {
            LOGGER.error(e.toString(), e);
        }
        throw new BzException("wav转文字失败!");
    }

    @Deprecated
    @ApiOperation(value = "上传pcm文件并转写")
    @PostMapping("/pcmConvert")
    @ResponseBody
    public ResponseEntity<String> pcmConvert(@RequestParam("file") MultipartFile file) {

        if (file.isEmpty() || !"pcm".equalsIgnoreCase(FileNameUtil.getSuffix(file.getOriginalFilename()))) {
            throw new BzException("上传pcm文件失败!");
        }

        String fileName = file.getOriginalFilename();
        try {

            // 临时 存储
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] bytes = file.getBytes();
            try {
                byteArrayOutputStream.write(bytes);
            } catch (IOException e) {
                try {
                    byteArrayOutputStream.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                e.printStackTrace();
                throw new BzException("获取文件内容失败!");
            }

            // 内存处理 pcm转wav
            ByteArrayOutputStream pcmStream = new ByteArrayOutputStream();
            PcmCovWavUtil.convertWaveFile(byteArrayOutputStream, pcmStream);

            Wav waveFile = new Wav();
            waveFile.GetFromBytes(pcmStream.toByteArray());

            String result = ApiUtils.sendToServer("qwertasd", waveFile.fs, waveFile.samples);
            LOGGER.info("fileName:[{}],result:[{}]", fileName, result);

            return   ResponseEntity.success(result);
        } catch (IOException e) {
            LOGGER.error(e.toString(), e);
        }
        throw new BzException("pcm转文字失败!");
    }

    @ApiOperation(value = "上传文件并保存")
    @PostMapping("/upload")
    @ResponseBody
    public ResponseEntity<String> upload(@RequestParam("file") MultipartFile file) {

        if (file.isEmpty()) {
            throw new BzException("上传文件失败!");
        }

        String fileName = file.getOriginalFilename();
        Path path = Paths.get("").toAbsolutePath().resolve("tempFile");
        String filePath = path.toAbsolutePath().toString() + File.separator;

        File dest = new File(filePath + fileName);
        try {
            dest.mkdirs();
            file.transferTo(dest);
            LOGGER.info(fileName + "上传成功");
            return   ResponseEntity.success(fileName + " 上传成功");
        } catch (IOException e) {
            LOGGER.error(e.toString(), e);
        }
        throw new BzException(fileName + "上传文件失败!");
    }

}
